
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "sequence.h"

int InitList(SeqList *List){
    List->list_head = NULL;
    List->list_length = 0;
    return(0);
}

int ListEmpty(SeqList List){
    if (List.list_length == 0 && List.list_head == NULL){
        return(1);
    }else if(List.list_head == NULL || List.list_length == 0){  //if ERR
        return(-1);
    }else{
        return(0);
    }
}

int ClearList(SeqList *List){
    if (List->list_head == NULL || List == NULL){
        return(EFAULT);
    }else{
        free(List->list_head); //Reclaim memory
        List->list_head = NULL;
        List->list_length = 0;
        return (0);
    }
}

int GetElem(SeqList List,unsigned int i,ElemType *e){
    if (i > List.list_length){
        return(EDOM);
    }else{
        memcpy(e,List.list_head+i-1,sizeof(ElemType)); //memcpy is easy to transplant
        return(0);
    }
}

int LocateElem(SeqList List,ElemType e){
    for (int i = 0; i < List.list_length; ++i) {
        if (memcmp(List.list_head+i,&e, sizeof(ElemType)) == 0){  //memcmp is easy to transplant
            return(i+1);
        }
    }
    return(0);
}

int ListInsert(SeqList *List,unsigned int i,ElemType e){
    if (i == 0){
        return(-1);
    }else if (List->list_head == NULL){
        List->list_head = calloc(i, sizeof(ElemType));  //dangerous ,failure to deal with the possibility of allocation failure
        List->list_length = i;
        memset(List->list_head,0,i* sizeof(ElemType));
        memcpy(List->list_head+i-1,&e, sizeof(ElemType));   //warn
        return((int)i);
    }else if (i > List->list_length){
        List->list_head = realloc(List->list_head,i);    ////dangerous
        memset(List->list_head+List->list_length,0,(i-List->list_length-1)* sizeof(ElemType));
        List->list_length = i;
        memcpy(List->list_head+i-1,&e, sizeof(ElemType));    //warn
        return((int)i);
    }else{
        List->list_head = realloc(List->list_head,++List->list_length);   //dangerous
        for (int j = (int)List->list_length; j > i; --j) {
            memcpy(List->list_head+j-1,List->list_head+j-2,sizeof(ElemType));  //warn
        }
        memcpy(List->list_head+i-1,&e,sizeof(ElemType));   //warn
        return(0);
    }
}

int ListDelete(SeqList *List,unsigned int i,ElemType *e){
    if (i==0 || i> List->list_length){
        return(EDOM);
    } else if (List->list_length == 1){
        memcpy(e,List->list_head,sizeof(ElemType));
        free(List->list_head);
        List->list_head = NULL;
        List->list_length = 0;
        return((int)i);
    } else{
        memcpy(e,List->list_head+i-1,sizeof(ElemType));
        for (int j = (int)i; j < List->list_length ; ++j) {
            memcpy(List->list_head+j-1,List->list_head+j, sizeof(ElemType));
        }
        List->list_head = realloc(List->list_head,--List->list_length);   //dangerous
        return(0);
    }
}

unsigned int ListLength(SeqList List){
    if (List.list_head == NULL && List.list_length == 0){
        return(0);
    } else if (List.list_length == 0){ //Fix the error
        free(List.list_head);
        return(0);
    }else{
        return(List.list_length);
    }
}